<?php
class TreeSet extends Object
{
	public static function Walk(&$tree, $child_key, $function, &$depth = 0)
	{
		foreach ($tree as $key => $node)
		{
			call_user_func_array($function, array(&$tree[$key], $depth));
			if (isset($tree[$key][$child_key]))
			{
				$depth++;
				self::Walk($tree[$key][$child_key], $child_key, $function, $depth);
				$depth--;
			}
		}
	}

	public static function GetFirstLeaf($tree, $child_key)
	{
		return isset($tree[$child_key]) ? self::GetFirstLeaf($tree[$child_key], $child_key) : $tree;
	}

	public static function Reverse($tree, $child_key, $new_childkey)
	{
		if (!isset($tree[$child_key])) return $tree;
		$parent = $tree[$child_key];
		unset($tree[$child_key]);
		$child = $tree;
		$parent[$new_childkey] = $child;
		return self::Reverse($parent, $child_key, $new_childkey);
	}

	public static function Flat($tree, $child_key, $out = array())
	{
		$tmp = $tree;
		unset($tmp[$child_key]);
        $out[] = $tmp;

		if (!isset($tree[$child_key])) return $out;

		$child = $tree[$child_key];
		return self::Flat($child, $child_key, $out);
	}

    public static function MergeBranch($tree, $branch)
	{
        foreach ($branch as $key => $node)
		{
			$tree[$key][$node] = $node;
		}
		return $tree;
	}

    public static function Get($tree, $path, $child_key)
    {
        $fields = explode(FS, $path);
        $field = array_shift($fields);
        $tree = array_get($tree, $field);
        if (!$tree) return;
        foreach($fields as $field)
        {
            $childs = array_get($tree, $child_key);
            if (is_array($childs) && array_key_exists($field, $childs))
                $tree = $childs[$field];
            else
                return;
        }
        return $tree;
    }
}
?>